package core.util;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.http.Cookie;

import org.eclipse.jdt.core.compiler.InvalidInputException;

public class StoredData
{
    public static final long TIME_OUT = 10000;

    public static final int REFRESH_COUNTER = 1000;

    public static ConcurrentMap<String, UserSessionData> storedSessionData = new ConcurrentHashMap<String, UserSessionData>();

    // public static Map<String, UserSessionData> storedSessionData = new
    // HashMap<String, UserSessionData>();

    public static boolean isCookieFresh( Cookie cookie ) {
        MyCookieValue val = null;
        try {
            val = new MyCookieValue( cookie.getValue() );
        } catch( InvalidInputException e ) {
            e.printStackTrace();
        }

        if( val == null ) {
            return false;
        }
        return isCookieFresh( val );
    }

    /**
     * Checks whether the given cookie exists and if it is fresh
     */
    public static boolean isCookieFresh( MyCookieValue val ) {
        if( val == null ) {
            return false;
        }

        UserSessionData data = getSessionData( val.getSessionId() );
        if( data == null ) {
            return false;
        }
        // check time stamp
        if( System.currentTimeMillis() - data.getLastActiveTime() > TIME_OUT ) {
            return false;
        }

        return true;
    }

    /**
     * Compares the incoming cookie version number against the one stored
     * 
     * @param val
     * @return <b>true</b> if version match; false otherwise.
     */
    public static boolean isCookieValid( MyCookieValue val ) {
        UserSessionData data = getSessionData( val.getSessionId() );
        if( data == null ) {
            return false;
        } else {
            return data.getCookieValue().equals( val );
        }
    }

    /**
     * Retrieves the stored session data based on session id
     * 
     * @param sessionId
     * @return stored data, or null of no data stored
     */
    private static UserSessionData getSessionData( String sessionId ) {
        return storedSessionData.get( sessionId );
    }

    /**
     * Synchronized method that removes stale session data; expensive. This is
     * called once every REFRESH_COUNTER times.
     */
    public static synchronized void removeStaleSessionData() {
        Set<String> entriesToRemove = new HashSet<String>();
        for( String sessionId : storedSessionData.keySet() ) {
            UserSessionData data = storedSessionData.get( sessionId );
            if( System.currentTimeMillis() - data.getLastActiveTime() > TIME_OUT ) {
                entriesToRemove.add( sessionId );
            }
        }

        for( String sessionId : entriesToRemove ) {
            storedSessionData.remove( sessionId );
        }
    }
}
